package com.vincent.utils;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.math.BigDecimal.ROUND_HALF_UP;

public final class CalculatorTool {
    private final static String string = "1.0*3.00/3.0000";
    /**
     * coin : USDT
     * logo : hongkong.aliyuncs.com/upload/20180615161908108.png
     * network : scsdfsdfueyendu3233nkmdsciudsn
     * identifier : $
     * price : 1
     * priceLimit : +0.11%
     */
//    private final static String string = "(1.001333+0.00133333)/3.001*(1.001+2.00133)";
//    private final static String string = "((((1+2*2+2-1+3*(1E4+2))*(2.00+(1+(1E+4-1+3)*8+1E+10+3-2/1+2/(1+5)+1)*5-2*10/2+(1+2)))))";

    private static int findMatchingRight(String expression, int leftIndex) {
        Stack<Integer> stack = new Stack<>();
        for (int i = leftIndex; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(') {
                stack.push(i);
            } else if (c == ')') {
                try {
                    stack.pop();
                } catch (Exception e) {
                    return -1;
                }
                if (stack.isEmpty()) {
                    return i;
                }
            }
        }
        return -1; // 如果没有匹配的右括号，返回-1或者其他合适的值
    }

    /**
     * 默认 ROUND_HALF_UP 10位小数
     *
     * @param optional
     * @return
     * @throws Exception
     */
    public static BigDecimal parseBigDecimal(String optional) throws Exception {
        String stringStr = getRealString(optional);
        extractSubExpressions(stringStr);
        checkNullKuoHao(stringStr);
        BigDecimal bigDecimal = calculateExpression(stringStr);
        bigDecimal = bigDecimal.setScale(10, ROUND_HALF_UP);
        return bigDecimal;
    }

    /**
     * 使用 HALF_UP 舍入模式：3.145 会被舍入为 3.15，因为小数部分大于等于 0.5。
     * 使用 HALF_DOWN 舍入模式：3.145 会被舍入为 3.14，因为小数部分大于 0.5。
     * 使用 CEILING 舍入模式：3.145 会被舍入为 3.15，因为向正无穷方向舍入。
     * 使用 FLOOR 舍入模式：3.145 会被舍入为 3.14，因为向负无穷方向舍入。
     * 使用 UP 舍入模式：3.145 会被舍入为 3.15，因为远离零方向舍入。
     * 使用 DOWN 舍入模式：3.145 会被舍入为 3.14，因为向零方向舍入。
     *
     * @param optional
     * @param scale
     * @param roundingMode
     * @return
     * @throws Exception
     */
    public static BigDecimal calculateBigDecimal(String optional, int scale, int roundingMode) throws Exception {
        String stringStr = getRealString(optional);
        extractSubExpressions(stringStr);
        checkNullKuoHao(stringStr);
        BigDecimal bigDecimal = calculateExpression(stringStr);
        bigDecimal = bigDecimal.setScale(scale, roundingMode);
        return bigDecimal;
    }

    public static String calculateString(String optional) throws Exception {
        String stringStr = getRealString(optional);
        extractSubExpressions(stringStr);
        checkNullKuoHao(stringStr);
        return calculateExpression(stringStr).toPlainString();
    }

    private static String getRealString(String stringStr) {
        String optionalTmp = stringStr.replace(" ", "");
        while (optionalTmp.startsWith("(") && optionalTmp.endsWith(")")) {
            String stringStrTmp = extractSubExpressionsClear(optionalTmp);
            if (!"".equals(stringStrTmp)) {
                optionalTmp = stringStrTmp;
            } else {
                break;
            }
        }
        //输出正确的
        return optionalTmp;
    }

    private static void extractSubExpressions(String expression) throws MyIllegalArgumentException {
//        LinkedHashMap<Integer, String> subExpressions = new LinkedHashMap<>();
        Stack<Integer> stack = new Stack<>();
        char[] tokens = expression.toCharArray();
        for (int i = 0; i < tokens.length; i++) {
            if (tokens[i] == '(') {
                stack.push(i);
            } else if (tokens[i] == ')') {
                if (!stack.isEmpty()) {
                    int startIndex = stack.pop();
                    if (i - startIndex == 1) {
                        throw new MyIllegalArgumentException("出现():" + expression);
                    }
                    String subExpression = expression.substring(startIndex + 1, i);
                    if (!subExpression.equals(expression.substring(1, expression.length() - 1))) {
                        if (subExpression.contains("(") && subExpression.contains(")")) {
                            extractSubExpressions(subExpression);
                        } else {
                            checkNull(subExpression);
                        }
//                        subExpressions.put(startIndex, subExpression);
                    }
                }
            }
        }
//        return subExpressions;
    }

    private static String extractSubExpressionsClear(String expression) {
        if (expression.startsWith("(")) {
            int matchingRight = findMatchingRight(expression, 0);
            if (matchingRight > 0 && matchingRight == expression.length() - 1 && expression.endsWith(")")) {
                expression = expression.substring(1, expression.length() - 1);
            } else {
                //结束了
                return "";
            }
        } else {
            //结束了
            return "";
        }
        return expression;
    }

    private static void checkNullKuoHao(String str) throws MyIllegalArgumentException {
        if (str.contains("=")) {
            throw new MyIllegalArgumentException("出现=:" + str);
        }
        //括号一定要成双成对
        if (!str.contains("(") && !str.contains(")")) {
            checkNull(str);
            return;
        }
        if (!str.contains("+") && !str.contains("-") && !str.contains("*") && !str.contains("/")) {
            throw new MyIllegalArgumentException(str);
        }
        //()
        if (str.contains("()")) {
            throw new MyIllegalArgumentException(str);
        }
        int lengthLeft = str.replace("(", "").length();
        int lengthRight = str.replace(")", "").length();
        if (lengthLeft != lengthRight) {
            throw new MyIllegalArgumentException("括号没有成对存在:" + str);
        }
    }

    private static void checkNull(String str) throws MyIllegalArgumentException {
        //公示计算，语法的长度至少也超过三个比如:3-1
        if (str.length() < 3 || str.contains("()")) {
            throw new MyIllegalArgumentException(str);
        }
        HashMap<String, String> map = new HashMap<>();
        map.put("/", "/");
        map.put("//", "//");
        map.put("*", "*");
        map.put("**", "**");
        map.put("+", "+");
        map.put("++", "++");
        map.put("--", "--");
        String oneStart = str.substring(0, 1);
        String twoStart = str.substring(0, 2);
        String oneEnd = str.substring(str.length() - 1);
        String twoEnd = str.substring(str.length() - 2);
        //开头出现语法错误
        if (map.containsKey(oneStart)) {
            throw new MyIllegalArgumentException("开头错误:" + oneStart);
        }
        if (map.containsKey(twoStart)) {
            throw new MyIllegalArgumentException("开头错误:" + twoStart);
        }
        //结尾现语法错误
        if (map.containsKey(oneEnd)) {
            throw new MyIllegalArgumentException("结尾错误:" + oneEnd);
        }
        if (map.containsKey(twoEnd)) {
            throw new MyIllegalArgumentException("结尾错误:" + twoEnd);
        }
        if ("-".endsWith(oneEnd)) {
            throw new MyIllegalArgumentException("结尾错误:" + oneEnd);
        }
        //先检查语法是否正确
        HashMap<String, String> addOp = new HashMap<>();
        addOp.put("+", "+");
        addOp.put("-", "-");
        addOp.put("*", "*");
        addOp.put("/", "/");
        str = str.replace("E+", "<自定义的分隔符>").replace("+", "<自定义的分隔符>").replace("-", "<自定义的分隔符>").replace("*", "<自定义的分隔符>").replace("/", "<自定义的分隔符>");
        String[] addOps = str.split("<自定义的分隔符>");
        for (int i = 0; i < addOps.length; i++) {
            if (addOps[i].startsWith(".") || addOps[i].endsWith(".")) {
                throw new MyIllegalArgumentException("数值错误:出现小数点开头或者结尾 --> " + addOps[i]);
            } else if (addOps[i].length() > 2 && addOps[i].startsWith("0") && !addOps[i].contains(".")) {
                throw new MyIllegalArgumentException("数值错误:出现不能以0开头 --> " + addOps[i]);
            } else {
                //又或者出现不相关字符，如果是正常的数字应该是可以解析的
                try {
                    new BigDecimal(addOps[i]).toPlainString();
                } catch (Exception e) {
                    throw new MyIllegalArgumentException("数值错误:" + addOps[i]);
                }
            }
        }
    }

    private static BigDecimal calculateExpression(String s) throws MyIllegalArgumentException {
        String postfixExpression = infixToPostfix(s);
        TreeNode root = buildExpressionTree(postfixExpression);
        return evaluateExpressionTree(root);
    }

    private static String infixToPostfix(String s) throws MyIllegalArgumentException {
        StringBuilder postfix = new StringBuilder();
        Stack<Character> operatorStack = new Stack<>();
        StringBuilder operand = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                continue;
            } else if (Character.isDigit(c) || c == '.') {
                while (i < s.length() && (Character.isDigit(s.charAt(i)) || s.charAt(i) == '.' || s.charAt(i) == 'E')) {
                    operand.append(s.charAt(i));
                    i++;
                    if (s.charAt(i - 1) == 'E' && s.length() != i && s.charAt(i) == '+') {
                        operand.append(s.charAt(i));
                        i++;
                    }
                }
                if (operand.toString().contains("E")) {
                    String temp = operand.toString();
                    operand.setLength(0);
                    if (temp.contains(".") || temp.contains("E")) {
                        System.out.println("temp");
                        operand.append(new BigDecimal(temp).setScale(20).toPlainString());
                    } else {
                        operand.append(temp);
                    }
                }
                if (operand.toString().startsWith(".")) {
                    throw new MyIllegalArgumentException("存在小数点开头:" + operand.toString());
                }
                postfix.append(operand.toString()).append(" ");
                operand.setLength(0);
                i--;
            } else if (c == '(') {
                operatorStack.push(c);
            } else if (c == ')') {
                while (!operatorStack.isEmpty() && operatorStack.peek() != '(') {
                    postfix.append(operatorStack.pop()).append(" ");
                }
                operatorStack.pop();
            } else {
                //如果现在的符号优先级低于或者等于最后一个，那就放进去，也就是说()低于+-；或者+-低于*/；或者()低于*/；或者+等于+； 或者-等于-；或者*等于*；或者/等于/；或者(等于(；或者)等于)；
                while (!operatorStack.isEmpty() && precedence(c) <= precedence(operatorStack.peek())) {
                    Character pop = operatorStack.pop();
                    postfix.append(pop).append(" ");
                }
                operatorStack.push(c);
            }
        }
        while (!operatorStack.isEmpty()) {
            Character pop = operatorStack.pop();
            postfix.append(pop).append(" ");
        }
        return postfix.toString().trim();
    }

    private static int precedence(char operator) {
        if (operator == '+' || operator == '-') {
            return 1;
        } else if (operator == '*' || operator == '/') {
            return 2;
        }
        return 0;
    }

    private static TreeNode buildExpressionTree(String postfix) {
        Stack<TreeNode> stack = new Stack<>();
        String[] tokens = postfix.split(" ");
        for (String token : tokens) {
            if (isNumeric(token)) {
                stack.push(new TreeNode(token));
            } else {
                TreeNode right = stack.pop();
                TreeNode left = stack.pop();
                TreeNode newNode = new TreeNode(token);
                newNode.left = left;
                newNode.right = right;
                stack.push(newNode);
            }
        }
        return stack.pop();
    }

    private static boolean isNumeric(String str) {
        try {
            new BigDecimal(str).toPlainString();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private static BigDecimal evaluateExpressionTree(TreeNode root) throws MyIllegalArgumentException {
        if (root == null) {
            return BigDecimal.ZERO;
        }

        if (root.left == null && root.right == null) {
            //是否有小数点
            int point = 0;
            if (null != root.value && root.value.contains(".")) {
                int i = root.value.indexOf(".") + 1;
                String substring = root.value.substring(i);
                System.out.println(root.value + "---" + "substring=" + substring);
                String replace = substring.replace("0", "");
                point = substring.length();
                if ("".equals(replace)) {
                    point = 0;
                }
            }
            if (point > 0) {
                BigDecimal bigDecimal = new BigDecimal(root.value);
                bigDecimal = bigDecimal.setScale(point, RoundingMode.DOWN);
                System.out.println("=============bigDecimal 1=" + bigDecimal.toPlainString());
                return bigDecimal;
            }
            BigDecimal bigDecimal = new BigDecimal(root.value);
            bigDecimal = bigDecimal.setScale(0, RoundingMode.DOWN);
            System.out.println("=============bigDecimal 2=" + bigDecimal.toPlainString());
            return bigDecimal;
        }
        BigDecimal leftValue = evaluateExpressionTree(root.left);
        BigDecimal rightValue = evaluateExpressionTree(root.right);

        switch (root.value) {
            case "+":
                return leftValue.add(rightValue);
            case "-":
                return leftValue.subtract(rightValue);
            case "*":
                return leftValue.multiply(rightValue);
            case "/":
                if (rightValue.equals(BigDecimal.ZERO)) {
                    throw new MyIllegalArgumentException("不能除以零");
                }
                return leftValue.divide(rightValue, 20, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO;
    }

    private static class TreeNode {
        String value;
        TreeNode left;
        TreeNode right;

        public TreeNode(String value) {
            this.value = value;
            this.left = null;
            this.right = null;
        }
    }

    private final static class MyIllegalArgumentException extends Exception {
        public MyIllegalArgumentException(String message) {
            super("IllegalArgumentException:表达式异常=>>" + message);
        }
    }

    public static void main(String[] args) {
//        Logger log = LoggerFactory.getLogger("日志：");
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_UP));     // 6
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_UP));     // 2
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_UP));     // 1
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_UP));    // -1
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_UP));    // -2
//        log.info("BigDecimal.ROUND_UP={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_UP));    // -6
//
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_DOWN));     // 5
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_DOWN));     // 1
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_DOWN));     // 1
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_DOWN));    // -1
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_DOWN));    // -1
//        log.info("BigDecimal.ROUND_DOWN={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_DOWN));    // -5
//
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_CEILING));     // 6
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_CEILING));     // 2
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_CEILING));     // 1
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_CEILING));    // -1
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_CEILING));    // -1
//        log.info("BigDecimal.ROUND_CEILING={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_CEILING));    // -5
//
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_FLOOR));     // 5
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_FLOOR));     // 1
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_FLOOR));     // 1
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_FLOOR));    // -1
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_FLOOR));    // -2
//        log.info("BigDecimal.ROUND_FLOOR={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_FLOOR));    // -6
//
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_HALF_UP));     // 6
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_HALF_UP));     // 2
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_HALF_UP));     // 1
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_HALF_UP));    // -1
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_HALF_UP));    // -2
//        log.info("BigDecimal.ROUND_HALF_UP={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_HALF_UP));    // -6
//
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_HALF_DOWN));     // 5
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_HALF_DOWN));     // 2
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_HALF_DOWN));     // 1
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_HALF_DOWN));    // -1
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_HALF_DOWN));    // -2
//        log.info("BigDecimal.ROUND_HALF_DOWN={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_HALF_DOWN));    // -5
//
//        //该模式是 ROUND_HALF_UP 和 ROUND_HALF_DOWN 的组合，但是比较特殊的是，
//        //如果被丢弃分数左边的数字是奇数，则行为与ROUND_HALF_UP（四舍五入）相同; 这句话的意思是：
//        //如果是偶数，则表现为ROUND_HALF_DOWN（五舍六入）。请注意，在对一系列计算重复应用时，这种舍入模式可以最小化累积误差。
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_HALF_EVEN));     // 6
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("6.5").setScale(0, BigDecimal.ROUND_HALF_EVEN));     // 6
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_HALF_EVEN));     // 2
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_HALF_EVEN));     // 1
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_HALF_EVEN));    // -1
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_HALF_EVEN));    // -2
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_HALF_EVEN));    // -6
//        log.info("BigDecimal.ROUND_HALF_EVEN={}", new BigDecimal("-6.5").setScale(0, BigDecimal.ROUND_HALF_EVEN));    // -6
//
//        //该模式认为传入的数据一定满足设置的小数模式，因此不需要舍入。如果在产生不精确结果的操作上指定了此舍入模式，则会抛出ArithmeticException。
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("5.5").setScale(0, BigDecimal.ROUND_UNNECESSARY));     // throw ArithmeticException
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("1.6").setScale(0, BigDecimal.ROUND_UNNECESSARY));     // throw ArithmeticException
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("1.0").setScale(0, BigDecimal.ROUND_UNNECESSARY));     // 1
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("-1.0").setScale(0, BigDecimal.ROUND_UNNECESSARY));    // -1
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("-1.6").setScale(0, BigDecimal.ROUND_UNNECESSARY));    // throw ArithmeticException
//        log.info("BigDecimal.ROUND_UNNECESSARY={}", new BigDecimal("-5.5").setScale(0, BigDecimal.ROUND_UNNECESSARY));    // throw ArithmeticException
//
//        BigDecimal dividend = new BigDecimal("10");
//        BigDecimal divisor = new BigDecimal("3");
//
//        try {
//            BigDecimal result = dividend.divide(divisor, 30, RoundingMode.UNNECESSARY);
//            System.out.println(result);
//        } catch (ArithmeticException e) {
//            System.out.println("无法精确计算结果");
//        }
//        try {
////            System.out.println(parseBigDecimal(string));
//            System.out.println(BigDecimal.valueOf(Double.MAX_VALUE).toPlainString());
//            System.out.println(BigDecimal.valueOf(Double.MAX_VALUE).toPlainString().length());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

//        System.out.println(isNumeric2("+1.100"));//true
//        System.out.println(isNumeric2("-1.100"));//true
//        System.out.println(isNumeric2("-1100"));//true
//        System.out.println(isNumeric2("+1100"));//true
//        System.out.println(isNumeric2("10E+4"));//true
//        System.out.println(isNumeric2("合理合法"));
//        System.out.println(isNumeric2(".00"));//true
//        System.out.println(isNumeric2("1.00"));//true
//        System.out.println(isNumeric2("-1"));//true
//        System.out.println(isNumeric2("1"));//true
//        System.out.println(isNumeric2("&"));
//        System.out.println(isNumeric2("^"));
//        System.out.println(isNumeric2("?"));
//        System.out.println(isNumeric2("/"));
//        System.out.println(isNumeric2(">"));
//        System.out.println(isNumeric2("》"));
//        System.out.println(isNumeric2("《"));
//        System.out.println(isNumeric2("\\"));
//        System.out.println(isNumeric2("/"));
//        System.out.println(isNumeric2("//"));
//        System.out.println(isNumeric2("["));
//        System.out.println(isNumeric2("]"));
//        System.out.println(isNumeric2("【"));
//        System.out.println(isNumeric2("】"));
//        System.out.println(isNumeric2("."));
//        System.out.println(isNumeric2("。"));
//        System.out.println(isNumeric2("～"));
//        System.out.println(isNumeric2("`"));
//        System.out.println(isNumeric2("~"));
//        System.out.println(isNumeric2("·"));
//        System.out.println(isNumeric2("@"));
//        System.out.println(isNumeric2("！"));
//        System.out.println(isNumeric2("!"));
//        System.out.println(isNumeric2("#"));
//        System.out.println(isNumeric2("#"));
//        System.out.println(isNumeric2("$"));
//        System.out.println(isNumeric2("¥"));
//        System.out.println(isNumeric2("*"));
//        System.out.println(isNumeric2("+"));
//        System.out.println(isNumeric2("-"));
//        System.out.println(isNumeric2("*"));
//        System.out.println(isNumeric2("("));
//        System.out.println(isNumeric2(")"));
//        System.out.println("购买".toUpperCase());
//        System.out.println("出售".toUpperCase());
//        System.out.println("Buy".toUpperCase());
//        System.out.println("Sell".toUpperCase());


    }

    public static boolean isNumeric2(String str) {
//        if (!checkStr(str))
//            return false;
        // 该正则表达式可以匹配所有的数字 包括负数
        Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
        String bigStr;
        try {
            bigStr = new BigDecimal(str).toPlainString();
        } catch (Exception e) {
//            e.printStackTrace();
//            System.out.println("Exception==" + e.getMessage());
            return false;//异常 说明包含非数字。
        }
        Matcher isNum = pattern.matcher(bigStr); // matcher是全匹配
        return isNum.matches();
    }



}